package com.guonl.feign.interceptor;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.TypeReference;
import com.guonl.feign.OpenApiFeign;
import com.guonl.service.OpenApiService;
import feign.RequestInterceptor;
import feign.RequestTemplate;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.http.client.utils.URIBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.http.HttpServletRequest;
import java.net.URISyntaxException;
import java.util.*;
import java.util.stream.Collectors;


@Slf4j
//@Component
public class OpenApiRequestInterceptor implements RequestInterceptor {

    private OpenApiService openApiService;

    public OpenApiRequestInterceptor(OpenApiService openApiService) {
        this.openApiService = openApiService;
    }

    @Override
    public void apply(RequestTemplate requestTemplate) {

        String apiKey = "";

        try {
            String whUserId = requestTemplate.headers().get("wh-user-id").stream().findFirst().get();
            apiKey = whUserId;
        } catch (Exception e) {
//            throw new RuntimeException(e);
        }

        //请求参数集合
        SortedMap<String, String> allParams = new TreeMap<>();

        //处理RequestParam
        Map<String, Collection<String>> queries = requestTemplate.queries();
        queries.forEach((key, value) -> {
            allParams.put(key, value.stream().collect(Collectors.joining(",")));
        });


        //处理请求body
        if (null != requestTemplate.body()) {
            int length = requestTemplate.body().length;
            if (0 < length) {
                String body = requestTemplate.requestBody().asString();
                if (StringUtils.isNotBlank(body)) {
                    Map<String, String> map = JSON.parseObject(body, new TypeReference<Map<String, String>>() {
                    });
                    allParams.putAll(map);
                }
            }
        }

        String queryjsonStr = JSON.toJSONString(allParams);
        log.info("请求参数:{}", queryjsonStr);

        long timestamp = System.currentTimeMillis();
        String method = requestTemplate.method();
        String url = requestTemplate.url();
        try {
            url = new URIBuilder(url).getPath();
        } catch (URISyntaxException e) {
            throw new RuntimeException(e);
        }

        String signatureString = String.format("%s\n%s\n%s\n%s", method, url, DigestUtils.sha512Hex(queryjsonStr), timestamp);
        log.info("拼接后的字符转:{}", signatureString);
        String apiSecret = getApiSecret(apiKey);
        String sign = getSign(apiSecret, signatureString);

        //设置header
        requestTemplate.header("KEY", apiKey);
        requestTemplate.header("SIGN", sign);
        requestTemplate.header("Timestamp", timestamp + "");

        log.info("FeignClient request headers:{}.", requestTemplate.headers());

    }

    public String getApiSecret(String apiKey) {
        return openApiService.getApiSecret(apiKey);
    }

    private String getSign(String apiSecret, String signatureString) {

        String signature = "";
        try {
            Mac hmacSha512 = Mac.getInstance("HmacSHA512");
            SecretKeySpec spec = new SecretKeySpec(apiSecret.getBytes(), "HmacSHA512");
            hmacSha512.init(spec);
            signature = Hex.encodeHexString(hmacSha512.doFinal(signatureString.getBytes()));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

        return signature;
    }

}
